/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.cabinetpermission.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.cabinetdoor.entity.BizCabinetDoor;
import vip.xiaonuo.biz.modular.cabinetdoor.service.BizCabinetDoorService;
import vip.xiaonuo.biz.modular.cabinetinfo.entity.BizCabinetInfo;
import vip.xiaonuo.biz.modular.cabinetinfo.mapper.BizCabinetInfoMapper;
import vip.xiaonuo.biz.modular.cabinetinfo.service.BizCabinetInfoService;
import vip.xiaonuo.biz.modular.cabinetpermission.entity.BizCabinetPermission;
import vip.xiaonuo.biz.modular.cabinetpermission.mapper.BizCabinetPermissionMapper;
import vip.xiaonuo.biz.modular.cabinetpermission.service.BizCabinetPermissionService;
import vip.xiaonuo.biz.modular.cabinetpermission.service.BizCabinetPermissionUtil;
import vip.xiaonuo.biz.modular.relation.enums.BizRelationCategoryEnum;
import vip.xiaonuo.biz.modular.relation.service.BizRelationService;

import javax.annotation.Resource;

/**
 * @author kongxm
 * @date 2022/11/20 17:04
 **/
@Service
public class BizCabinetPermissionUtilImpl implements BizCabinetPermissionUtil {
    @Resource
    private BizRelationService bizRelationService;
    @Resource
    private BizCabinetInfoService bizCabinetInfoService;
    @Resource
    private BizCabinetDoorService bizCabinetDoorService;

    public void hasPermission(String cabinetGroupId, String cabinetInfoId, String cabinetDoorId) {
        if (StringUtils.isNotEmpty(cabinetDoorId)) {
            // 判断是否有柜门权限
            boolean exist = existCabinetDoorPerm(cabinetDoorId);
            if (exist) return;

            // 柜门权限不存在，根据柜门id查找柜门，得到柜子id
            BizCabinetDoor bizCabinetDoor = bizCabinetDoorService.getById(cabinetDoorId); // 查找柜门
            Assert.isTrue(bizCabinetDoor != null, "非柜门管理员无法操作");

            // 判断柜子id是否有权限
            exist = existCabinetInfoPerm(bizCabinetDoor.getCabinetInfoId());
            if (exist) return;

            // 柜子id也没有权限，根据柜子id查找组柜
            BizCabinetInfo bizCabinetInfo = bizCabinetInfoService.getById(bizCabinetDoor.getCabinetInfoId()); // 查找组柜
            Assert.isTrue(bizCabinetInfo != null, "非柜门管理员无法操作");

            // 判断组柜是否有权限
            exist = existCabinetGroupPerm(bizCabinetInfo.getCabinetGroupId());
            Assert.isTrue(exist, "非柜门管理员无法操作");
            return;
        }
        if (StringUtils.isNotEmpty(cabinetInfoId)) {
            boolean exist = existCabinetInfoPerm(cabinetInfoId);
            if (exist) return;

            BizCabinetInfo bizCabinetInfo = bizCabinetInfoService.getById(cabinetInfoId); // 查找柜子
            Assert.isTrue(bizCabinetInfo != null, "非柜子管理员无法操作");

            exist = existCabinetGroupPerm(bizCabinetInfo.getCabinetGroupId());
            Assert.isTrue(exist, "非柜子管理员无法操作");
            return;
        }
        if (StringUtils.isNotEmpty(cabinetGroupId)) {
            boolean exist = existCabinetGroupPerm(cabinetGroupId);
            Assert.isTrue(exist, "非组柜管理员无法操作");
        }
    }

    private boolean existCabinetGroupPerm(String cabinetGroupId) {
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        if (StpUtil.hasRoleOr("superAdmin", "sysAdmin")) return true;
        String userId = saBaseLoginUser.getId();

        if (StringUtils.isEmpty(cabinetGroupId)) return false;
        return bizRelationService.getRelationTargetIdListByObjectIdAndCategory(cabinetGroupId,
                BizRelationCategoryEnum.BIZ_RELATION_CABINET_GROUP_AND_ADMIN_USER.getValue())
                .stream().anyMatch(id -> id.equals(userId));
    }

    private boolean existCabinetInfoPerm(String cabinetInfoId) {
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        if (StpUtil.hasRoleOr("superAdmin", "sysAdmin")) return true;
        String userId = saBaseLoginUser.getId();

        if (StringUtils.isEmpty(cabinetInfoId)) return false;
        return bizRelationService.getRelationTargetIdListByObjectIdAndCategory(cabinetInfoId,
                BizRelationCategoryEnum.BIZ_RELATION_CABINET_INFO_AND_ADMIN_USER.getValue())
                .stream().anyMatch(id -> id.equals(userId));
    }

    private boolean existCabinetDoorPerm(String cabinetDoorId) {
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        if (StpUtil.hasRoleOr("superAdmin", "sysAdmin")) return true;
        String userId = saBaseLoginUser.getId();

        if (StringUtils.isEmpty(cabinetDoorId)) return false;
        return bizRelationService.getRelationTargetIdListByObjectIdAndCategory(cabinetDoorId,
                BizRelationCategoryEnum.BIZ_RELATION_CABINET_DOOR_AND_ADMIN_USER.getValue())
                .stream().anyMatch(id -> id.equals(userId));
    }
}
